package com.yunquan.ohana.http

import com.yunquan.ohana.BuildConfig
import com.yunquan.ohana.http.cooike.CookieJarImpl
import com.yunquan.ohana.http.cooike.store.MemoryCookieStore
import com.yunquan.ohana.http.interceptor.logging.Level
import com.yunquan.ohana.http.interceptor.logging.LoggingInterceptor
import com.yunquan.ohana.utils.SPUtils
import com.yunquan.ohana.utils.SystemUtils
import com.yunquan.ohana.utils.Utils
import okhttp3.Cache
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.internal.platform.Platform
import retrofit2.Retrofit
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.util.concurrent.TimeUnit

/**
 * $
 * @author yjp
 * @date 2020/4/1 16:24
 */
class BaseHttp {

    companion object {
        //最大缓存
        const val MAX_CACHE_SIZE = 1024 * 1024 * 50L

        //链接超时
        const val CONNECT_TIME_OUT = 30L

        //读取超时
        const val READ_TIME_OUT = 600L

        //请求超时
        const val WRITE_TIME_OUT = 30L

        val MEDIA_TYPE_JSON = "application/json; charset=utf-8".toMediaType()

        val instance: BaseHttp by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            BaseHttp()
        }

        val api by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { instance.getAPI() }

        /**
         * 隐私政策
         * http://43.153.46.236/terms-of-use
         */
        val mTermsOfUse by lazy { "${instance.baseUrl}/terms-of-use" }

        /**
         * 隐私政策
         * http://43.153.46.236/privacy-policy
         */
        val mPrivacyPolicyUrl by lazy { "${instance.baseUrl}/privacy-policy" }
    }

    private var retrofit: Retrofit? = null
    private var client: OkHttpClient? = null

    /**
     * BaseUrl
     */
//    private val baseUrl: String = "https://ohana.dayitc.com"
    private val baseUrl: String = "http://192.168.0.12:18081"

    /**
     * 同步创建API
     */
    @Synchronized
    fun getAPI(): ApiService {
        return getRetrofit().create(ApiService::class.java)
    }

    /**
     * 重置
     */
    fun reset() {
        retrofit = null
        retrofit = initRetrofit()
    }

    /**
     * 初始Retrofit
     */
    @Synchronized
    fun getRetrofit(): Retrofit {
        if (retrofit == null) {
            synchronized(BaseHttp) {
                retrofit = initRetrofit()
            }
        }
        return retrofit!!
    }

    /**
     * 初始化Retrofit
     */
    private fun initRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(getOkClient())
            .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    /**
     * 初始化OkHttp客户端
     */
    @Synchronized
    fun getOkClient(): OkHttpClient {
        if (client == null) {
            synchronized(BaseHttp) {
                client = initClient()
            }
        }
        return client!!
    }

    /**
     * 初始化OkHttpClient
     */
    private fun initClient(): OkHttpClient {
        val mLoggingInterceptor = LoggingInterceptor.Builder()
            .loggable(BuildConfig.DEBUG)
            .setLevel(Level.BASIC)
            .log(Platform.INFO)
            .request("Request")
            .response("Response")
            .addHeader("version", BuildConfig.VERSION_NAME)
            .addHeader("phoneModel", SystemUtils.PHONE_MODEL)
            .build()
        val cacheFile = File(Utils.instance.context.cacheDir, "YJP_cache")
        val cache = Cache(cacheFile, MAX_CACHE_SIZE)
        return OkHttpClient.Builder()
            .addInterceptor(mHeaderInterceptor)
            .addInterceptor(mLoggingInterceptor)
            .cookieJar(CookieJarImpl(MemoryCookieStore()))
            .cache(cache)
            .connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
            .readTimeout(READ_TIME_OUT, TimeUnit.SECONDS)
            .writeTimeout(WRITE_TIME_OUT, TimeUnit.SECONDS)
            .retryOnConnectionFailure(true)
            .build()
    }

    private val mHeaderInterceptor = Interceptor {
        val originalRequest = it.request()
        val request = originalRequest.newBuilder()
            .addHeader("token", SPUtils.getString("token"))
            .addHeader("Content-Type", "application/json;charset=UTF-8")
            .method(originalRequest.method, originalRequest.body)
            .build()
        it.proceed(request)
    }

}